Query Language

NOTE: We should look at http://jakarta.apache.org/commons/jxpath/

xjavadoc is based on Collection and uses commons-collections' Predicate interface to filter various Collections. xjavadoc/xdoclet2 has some basic implementations of the Predicate interface. There are basic logical operators such as And, Or and Not, but also Predicates that evaluate an xjavadoc API object, such as HasTag, IsA, etc.

Most methods in the xjavadoc API that return a Collection can also take as input a Predicate argument. Example:

/**
 * @return a Collection of XMethod that have a @foo.bar tag.
 */
public Collection getFooBarMethods(XClass clazz) {
  HasTag hasTag = new HasTag();
  hasTag.setTagName("foo.bar");
  Collection methods = clazz.getMethods();
}

This is very convenient to express in Java code. You could access this functionality from Velocity too:

#foreach( $methods in $myutil.getFooBarMethods($class) )
   do something with the method here.
#end

This reminds us of the XDoclet 1 tag handlers. You code some logic in the java class, and you access it from the template. The only difference now is that XDoclet 2's "tag handlers" do not perform looping and branching logic, since Velocity/Jelly has that built-in. Instead, these XDoclet 2 "tag handlers" would return Collections (for looping), booleans (for conditionals) or Strings (for content).

This approach is nice in some scenarios, especially when you want to share the logic in these java classes among many templates. We'll definitely need it.

However, it would be nice to have an optional approach too. Imagine if all you had to write was this:

#foreach( $method in $class.getMethods("select method where method.doc.tag.name='foo.bar'") )
   do something with the method here.
#end

And no need to write a separate java class or getFooBarMethods class. A query language! This would make it even easier to write plugins for XDoclet.

Of course, this means you're mixing logic and presentation in the same file, and violates anything MVC has taught us. But XDoclet plugin writers often want to get a job done as easily as possible, and having a simple, albeit a bit dirty, way to prototype templates like this would be an enormous achievement.

Implementation

We'd have to define a grammar for the query language and generate a parser for it with JavaCC, ANTLR or something else. I suggest we look at Hibernate and see how they have implemented their query parser. After all, the grammar will be quite similar. SQLish. -And very simple.

Maybe we don't need any fancy parser either, just use introspection in the same way as velocity does.

When we have a parser that understands query expressions, we'd have something that could generate Predicate objects on the fly, and from there it's business as usual.